package com.fastadmin.config.security.simple;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.fastadmin.common.FAConst;
import com.fastadmin.common.cookie.CookieUtils;
import com.fastadmin.common.jedis.JedisTemplate;
import com.fastadmin.pojo.User;
import com.fastadmin.thread.UserThreadLocal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.security.jwt.crypto.sign.RsaVerifier;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**拦截请求进行token验证
 * @author YangKun
 * @date 2019/4/3 15:03.
 */
public class JwtHeadFilter extends OncePerRequestFilter {
    private RsaVerifier verifier;
    private JedisTemplate jedisTemplate;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//        String token = request.getHeader("Authentication");
        String token = CookieUtils.getCookieValue(request, FAConst.LoginConst.COOKIE_NAME);
        if (StrUtil.isBlank(token) || token.isEmpty()) {
            filterChain.doFilter(request, response);
            return;
        }

        JwtUser user;
        try {
            Jwt jwt = JwtHelper.decodeAndVerify(token, verifier);
            String claims = jwt.getClaims();
            user = JSON.parseObject(claims, JwtUser.class);
            //做一点验证之外的操作

            String username = user.getUsername();
            String json = jedisTemplate.get(FAConst.LoginConst.REDIS_USER_PREFIX + username);
            if (StrUtil.isEmpty(json)) {
                throw new Exception("登陆过期");
            }
            User DB_USER = JSONUtil.toBean(json, User.class);
            request.setAttribute("DB_USER", DB_USER);
            UserThreadLocal.set(DB_USER);
            //todo: 可以在这里添加检查用户是否过期,冻结...
        }catch (Exception e){
            //这里也可以filterChain.doFilter(request,response)然后return,那最后就会调用
            //.exceptionHandling()nenene-t.authenticationEntryPoint,也就是本列中的"需要登陆"
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write("token 失效，请重新登录");
            response.sendRedirect("/logout");

            return;
        }
        JwtLoginToken jwtLoginToken = new JwtLoginToken(user, user.getPassword(), user.getAuthorities());
        jwtLoginToken.setDetails(new WebAuthenticationDetails(request));
        SecurityContextHolder.getContext().setAuthentication(jwtLoginToken);
        filterChain.doFilter(request,response);
    }


    public void setVerifier(RsaVerifier verifier) {
        this.verifier = verifier;
    }

    public void setJedisTemplate(JedisTemplate jedisTemplate) {
        this.jedisTemplate = jedisTemplate;
    }
}
